package com.book.common.util;


import com.book.common.tree.DataTree;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.util.CollectionUtils;

import java.util.List;
import java.util.Map;
import java.util.Optional;
import java.util.Set;

/**
 * Description：
 * @Author： leo.xiong
 * @CreateDate： 2019/8/13 16:29
 * @Email： leo.xiong@suyun360.com
 * Version：1.0
 */
@Slf4j
public class TreeUtil {

    /**
     * 新建树，是否默认添加最上层
     *
     * @param nodes
     * @param <T>
     * @return
     */
    public static <T> DataTree<T> buildDataTree(List<T> nodes) {
        DataTree<T> root = new DataTree<>();
        root.setId(DataTree.FIRST_INDEX_ID);
        root.setParentId(DataTree.EMPTY_INDEX_ID);
        root.setHasParent(false);
        root.setChecked(false);
        if (CollectionUtils.isEmpty(nodes)) {
            root.setHasChild(false);
            return root;
        }
        root.setHasChild(true);
        Map<Long, Set<DataTree<T>>> dataTreeSetMap = Maps.newHashMap();
        for (T node : nodes) {
            DataTree<T> dataTree = new DataTree<>();
            BeanUtils.copyProperties(node, dataTree);
            if (!isBuildTreeDataObject(dataTree)) {
                continue;
            }
            dataTree.setData(node);
            Long parentId = Optional.ofNullable(dataTree.getParentId()).orElse(DataTree.FIRST_INDEX_ID);
            Set<DataTree<T>> dataTreeSet = dataTreeSetMap.get(parentId);
            if (dataTreeSet == null) {
                dataTreeSet = Sets.newTreeSet();
                dataTreeSetMap.put(parentId, dataTreeSet);
            }
            dataTreeSet.add(dataTree);
        }
        buildChildrenNode(root, dataTreeSetMap);
        return root;
    }

    /**
     * 递归拼接子节点
     *
     * @param dataTree
     * @param dataTreeSetMap
     * @param <T>
     */
    private static <T> void buildChildrenNode(DataTree<T> dataTree, Map<Long, Set<DataTree<T>>> dataTreeSetMap) {
        Long id = dataTree.getId();
        Set<DataTree<T>> dataTreeSet = dataTreeSetMap.get(id);
        if (CollectionUtils.isEmpty(dataTreeSet)) {
            return;
        }
        dataTree.setChildren(dataTreeSet);
        for (DataTree<T> tDataTree : dataTreeSet) {
            buildChildrenNode(tDataTree, dataTreeSetMap);
        }
    }

    /**
     * 对象是否可以建树
     *
     * @param dataTree
     * @return
     */
    private static <T> boolean isBuildTreeDataObject(DataTree<T> dataTree) {
        if (dataTree == null) {
            log.info("DataTree对象不能为空");
            return false;
        }
        if (dataTree.getId() == null) {
            log.info("DataTree对象ID不能为空");
            return false;
        }
        if (dataTree.getOrderNum() == null) {
            log.info("DataTree对象排序字段不能为空");
            return false;
        }
        return true;
    }
}
